package com.caocaog.market.finance.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caocaog.market.finance.entity.FinanceGroup;
import com.caocaog.market.finance.enums.WithdrawStatus;
import com.caocaog.market.finance.enums.WithdrawType;
import com.caocaog.market.finance.service.FinanceGroupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.GenericController;
import org.jeecg.common.system.domain.QueryRequest;
import org.jeecg.common.system.query.PageGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.online.config.exception.BusinessException;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.*;

import static com.caocaog.market.finance.enums.WithdrawStatus.*;
import static com.caocaog.market.finance.enums.WithdrawType.MERCHANT;
import static com.caocaog.market.finance.enums.WithdrawType.SITE;
import static java.util.stream.Collectors.toMap;

@Slf4j
@Validated
@RestController
@RequestMapping("financeGroup")
public class FinanceGroupController extends GenericController<FinanceGroup, FinanceGroupService> {


    @PostMapping("page")
    public Result<IPage<FinanceGroup>> queryGroupPage(@RequestBody(required = false) FinanceGroup financeGroup, QueryRequest queryRequest) {
        try {
            Page<FinanceGroup> page = PageGenerator.createPageSort(queryRequest);
            LoginUser currentUser = getLoginUser();
            financeGroup = Optional.ofNullable(financeGroup).orElse(new FinanceGroup());
            if (currentUser.getUserType() == 2) {
                financeGroup.setType(SITE);
                financeGroup.setSiteId(Optional.ofNullable(currentUser.getSiteId()).orElseThrow(() -> new BusinessException("分站用户未绑定分站")));
            } else if (currentUser.getUserType() == 3) {
                financeGroup.setType(MERCHANT);
                financeGroup.setMerchantId(Optional.ofNullable(currentUser.getMerchantId()).orElseThrow(() -> new BusinessException("商家用户未绑定商家")));
            }
            return Result.OK(service.queryFinanceGroupPage(page, financeGroup));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("查询提现行分页信息失败, " + e.getMessage());
        }
    }


    @GetMapping("maxCount")
    public Result<Integer> getMaxWithdrawCount() {
        return Result.OK(FinanceGroupService.MAX_WITHDRAW_COUNT);
    }


    @GetMapping("status")
    public Result<Map<Integer, String>> getWithdrawStatus() {
        return Result.OK(Arrays.stream(WithdrawStatus.values()).filter(status ->
                status.getTypes().contains(WithdrawStatus.Type.GROUP)
        ).collect(toMap(WithdrawStatus::getCode, WithdrawStatus::getName)));
    }


    @PostMapping("apply")
    public Result<Objects> applyWithdrawal(@RequestBody List<Long> financeLineIds) {
        WithdrawType type = null;
        String siteId = null;
        String merchantId = null;

        try {
            LoginUser currentUser = getLoginUser();
            if (currentUser.getUserType() == 1)
                throw new BusinessException("系统用户不能创建提现集");
            else if (currentUser.getUserType() == 2) {
                type = SITE;
                siteId = Optional.ofNullable(currentUser.getSiteId()).orElseThrow(() -> new BusinessException("分站用户未绑定分站"));
            } else if (currentUser.getUserType() == 3) {
                type = MERCHANT;
                merchantId = Optional.ofNullable(currentUser.getMerchantId()).orElseThrow(() -> new BusinessException("商家用户未绑定商家"));
            }

            Assert.notNull(financeLineIds, "提现集不能为空");
            Assert.notNull(type, "提现类型不能为空");

            service.applyWithdrawal(financeLineIds, type, siteId, merchantId);
            return Result.OK();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("申请提现失败, " + e.getMessage());
        }
    }


    @PutMapping("updateAlipay")
    public Result<Integer> updateAlipayAccount(@RequestBody FinanceGroup financeGroup) {
        try {
            String alipayAccount = financeGroup.getAlipayAccount();
            String alipayName = financeGroup.getAlipayName();
            Assert.isTrue(StringUtils.isNotBlank(alipayAccount), "支付宝账号不能为空");
            Assert.isTrue(StringUtils.isNotBlank(alipayName), "支付宝姓名不能为空");

            return Result.OK(service.updateFinanceGroup(new FinanceGroup()
                    .setAlipayAccount(alipayAccount)
                    .setAlipayName(alipayName)
                    .setId(financeGroup.getId())
            ));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("更新提现组支付宝账户信息失败, " + e.getMessage());
        }
    }


    @DeleteMapping("delete{id}")
    public Result<Integer> deleteGroup(@NotNull @PathVariable Long id) {
        try {
            return Result.OK(service.deleteFinanceGroup(id));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("删除提现组失败, " + e.getMessage());
        }
    }


    @PutMapping("audit")
    public Result<Integer> auditGroup(@RequestParam @NotNull Long id,
                                      @RequestParam @NotNull Boolean isPass,
                                      @RequestParam(required = false) String rejectReason) {
        try {
            // isPass为true时, 审核通过（待转账）, 否则为驳回
            WithdrawStatus status = isPass ? PENDING_TRANSFER : REJECT;
            if (!isPass && StringUtils.isBlank(rejectReason)) throw new BusinessException("驳回原因不能为空");
            return Result.OK(service.auditFinanceGroup(id, status, rejectReason));
        } catch (Exception e) {
            throw new RuntimeException("审核提现组失败, " + e.getMessage());
        }
    }


    @PutMapping("transfer{id}")
    public Result<String> transferGroup(@NotNull @PathVariable Long id) {
        try {
            String errorMessage = service.transferFinanceGroup(id);
            if (errorMessage != null) return Result.error(null, errorMessage);

            return Result.OK();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("提现组转账失败, " + e.getMessage());
        }
    }


    @GetMapping("dataTransfer")
    public void dataTransfer() {
        try {
            service.dataTransfer();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("转移数据失败, " + e.getMessage());
        }
    }

    @GetMapping("updateLine")
    public void updateLine() {
        try {
            service.updateLine();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("更新转移的数据失败, " + e.getMessage());
        }
    }


}
